package com.sztx.pay.center.core.service.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSONObject;
import com.sztx.pay.center.common.util.Constance;
import com.sztx.pay.center.common.util.Constance.CallBackOrderState;
import com.sztx.pay.center.common.util.Constance.GuaranteeType;
import com.sztx.pay.center.common.util.Constance.TradeMessageType;
import com.sztx.pay.center.common.util.Constance.TradeOrderType;
import com.sztx.pay.center.core.service.CallBackService;
import com.sztx.pay.center.core.service.ConfirmOrderService;
import com.sztx.pay.center.core.service.MqMessageService;
import com.sztx.pay.center.core.service.PayCoreCallBack;
import com.sztx.pay.center.core.service.bean.CallBackInfo;
import com.sztx.pay.center.core.service.bean.PayCoreTradeInfo;
import com.sztx.pay.center.core.service.bean.rpc.TradeFlowMessage;
import com.sztx.pay.center.dataaccess.dao.mysql.OrderB2cMysqlDAO;
import com.sztx.pay.center.dataaccess.dao.mysql.OrderConfirmDetailMysqlDAO;
import com.sztx.pay.center.dataaccess.domain.OrderB2cDO;
import com.sztx.pay.center.dataaccess.domain.OrderConfirmDetailDO;
import com.sztx.se.core.service.impl.BaseServiceImpl;

@Service
public class ConfirmOrderServiceImpl extends BaseServiceImpl implements ConfirmOrderService,PayCoreCallBack {

	@Autowired
	OrderB2cMysqlDAO orderB2cMysqlDAO;
	
	@Autowired
	CallBackService callBackService;
	
	@Autowired
	OrderConfirmDetailMysqlDAO orderConfirmDAO;
	
	@Autowired
	private MqMessageService mqMessageService;
	@Override
	public void callPayResult(PayCoreTradeInfo tradeInfo) {
		
		LOG.info("into core confirmOrder CallBack");
		String referOrderId = tradeInfo.getReferOrderId();
		int payFlowState = tradeInfo.getPayFlowState().getCode();
		String payFlowDesc = tradeInfo.getPayFlowDesc();
		LOG.info("core confirmOrderCallBack referOrderId:" + referOrderId);
		LOG.info("core confirmOrderCallBack payFlowState:" + payFlowState);
		
		OrderB2cDO orderB2cDO = orderB2cMysqlDAO.findById(referOrderId);
		
		if (orderB2cDO != null && (orderB2cDO.getOrderStatus() == Constance.B2COrderState.SETTLING.getCode() || orderB2cDO.getOrderStatus() == Constance.B2COrderState.REFUND_SUCCESS.getCode())) {
			//更新订单状态
			OrderB2cDO updateOrderB2cDO = new OrderB2cDO();
			if (orderB2cDO.getOrderStatus() != Constance.B2COrderState.REFUND_SUCCESS.getCode()) {
				if (payFlowState == Constance.PayFlowState.SUCCESS.getCode()) {
					updateOrderB2cDO.setOrderStatus(Constance.B2COrderState.TRADE_OVER.getCode());
					updateOrderB2cDO.setOrderDesc(Constance.B2COrderState.TRADE_OVER.getDesc());
					updateOrderB2cDO.setSettleTime(new Date());
				}
				if (payFlowState == Constance.PayFlowState.FAIL.getCode()) {
					updateOrderB2cDO.setOrderStatus(Constance.B2COrderState.SETTLE_FAIL.getCode());
					updateOrderB2cDO.setOrderDesc(payFlowDesc);
				}
				if (payFlowState == Constance.PayFlowState.EXCEPTION.getCode()) {
					updateOrderB2cDO.setOrderStatus(Constance.B2COrderState.SETTLE_EXCEPTION.getCode());
					updateOrderB2cDO.setOrderDesc(payFlowDesc);
				}
				updateOrderB2cDO.setTradeOrderId(referOrderId);
				orderB2cMysqlDAO.updateInfo(updateOrderB2cDO);
			}
			//通知业务系统
			CallBackInfo callBackInfo = new CallBackInfo();
			callBackInfo.setTradeOrderId(referOrderId);
			callBackInfo.setOutOrderId(orderB2cDO.getOrderId());
			callBackInfo.setNotfiyUrl(orderB2cDO.getNotifyUrl());
			callBackInfo.setReturnUrl(orderB2cDO.getReturnUrl());
			callBackInfo.setTotalFee(orderB2cDO.getFee());
			callBackInfo.setPayAmount(orderB2cDO.getTradeAmount().intValue());
			callBackInfo.setAttach(orderB2cDO.getAttach());
			callBackInfo.setPayTime(new Date());
			callBackInfo.setTradeCrateTime(orderB2cDO.getAddTime());
			callBackInfo.setOrderType(TradeOrderType.SETTLE_ORDER);
			callBackInfo.setOrderDesc(tradeInfo.getPayFlowDesc());
			if (payFlowState == Constance.PayFlowState.FAIL.getCode() ) {
				callBackInfo.setOrderState(CallBackOrderState.FAIL);
			} else if (payFlowState == Constance.PayFlowState.EXCEPTION.getCode() ){
				callBackInfo.setOrderState(CallBackOrderState.EXCEPTION);
			} else {
				callBackInfo.setOrderState(CallBackOrderState.SUCCESS);
			}
			
			if (orderB2cDO.getGuaranteeType() == GuaranteeType.ORDINARY.getCode() && payFlowState != Constance.PayFlowState.WAITING_PAY.getCode() && payFlowState != Constance.PayFlowState.PAYING.getCode()) {
				TradeFlowMessage message = new TradeFlowMessage();
				
				List<OrderConfirmDetailDO> findByTradeOrderId = orderConfirmDAO.findByTradeOrderId(referOrderId);
				long receiveAmount = 0;
				if (!CollectionUtils.isEmpty(findByTradeOrderId)){
					for (OrderConfirmDetailDO orderConfirmDetailDO : findByTradeOrderId) {
						if (orderB2cDO.getPayeeUserId().equals(orderConfirmDetailDO.getUserId())) {
							receiveAmount += orderConfirmDetailDO.getAmount();
						}
					}
				}
				message.setTradeType(TradeMessageType.SETTLE.getCode());
				message.setBerbonAcc(orderB2cDO.getPayeeUserId());
				message.setBusinessType(orderB2cDO.getBusinessType());
				if (orderB2cDO.getOrderStatus() == Constance.B2COrderState.REFUND_SUCCESS.getCode()) {
					message.setTradeAmount(orderB2cDO.getPayAmount());
					message.setProfit(0);
				} else {
					message.setTradeAmount(orderB2cDO.getTradeAmount());
					message.setProfit(orderB2cDO.getTradeAmount() - receiveAmount - orderB2cDO.getFee());
				}
				message.setReceiveAmount(receiveAmount);
				message.setOtherBerbonAcc(orderB2cDO.getPayerUserId());
				message.setPayOrderNo(referOrderId);
				message.setTradeOrderNo(orderB2cDO.getOrderId());
				message.setFee(orderB2cDO.getFee());
				
				sendTradeFlowMessage(message);
				callBackService.callBack(callBackInfo);
			}
		}
	}
	private boolean sendTradeFlowMessage(TradeFlowMessage message) {
		String json = JSONObject.toJSONString(message);
		mqMessageService.sendTradeFlowMsg(json);
		return true;
	}
}
